/**
 * 静态方法
 * Name = socketManager
 * DateTime = Wed Jan 19 2022 13:37:45 GMT+0800 (中国标准时间)
 * Author = Created by zhj9922
 * FileBasename = socketManager.ts
 * gitee： https://gitee.com/coyeking
 */
 const io = (window as any).io || {};
import { _decorator, Component, game } from 'cc';
const { ccclass, property } = _decorator;
 
@ccclass('socketManager')
export class socketManager {
	private static _instance: socketManager;
    
    private sio = null;
    private connected:boolean = false;
    private isPinging:boolean = false;
    private lastRecieveTime:number = 0;
    private fnDisconnect = null;
    private  handlers = [];
	
    static get instance () {
        if (this._instance) {
            return this._instance;
        }

        this._instance = new socketManager();
        return this._instance;
    };
	
    /** 
     * 初始化
    */
     connect(socket_ip:string,callback?:Function){
        let opts = {
            'reconnection':false,
            'force new connection': true,
            'transports':['websocket', 'polling']
        }
        this.sio = io.connect(socket_ip,opts);

        this.sio.on('connect',(data)=>{
            console.log('socket connect success!');
            this.connected = true;
            callback && callback();
        })

        this.sio.on('disconnect',(data)=>{
            console.log('socket disconnect!');
            this.connected = false;
        });
        
        for(var key in this.handlers){
            var value = this.handlers[key];
            if(typeof(value) == "function"){
                if(key == 'disconnect'){
                    this.fnDisconnect = value;
                }
                else{
                    console.log("register:function " + key);
                    this.sio.on(key,value);                        
                }
            }
        }

        this.startHearbeat();
    }

    /** 
     * 获取客户端实体
    */
    getClient(){
        return this.sio;
    }

    /** 
     * 开启心跳包
    */
    startHearbeat(){
        this.sio.on('game_pong',()=>{
            console.log('game_pong');
            this.lastRecieveTime = Date.now();
        });
        this.lastRecieveTime = Date.now();
        if(!this.isPinging){
            this.isPinging = true;
            setInterval(()=>{
                if(this.sio){
                    this.ping();                
                }
            },2000);
            setInterval(()=>{
                if(this.sio){
                    if(Date.now() - this.lastRecieveTime > 10000){
                        this.close();
                    }         
                }
            },500);
        }   
    }

    /** 
     * ping
    */
    ping(){
        if(this.sio){
            this.emit('game_ping');
        }
    }

    /** 
     * 关闭
    */
    close(){
        console.log('connect close');
        if(this.sio && this.connected){
            this.connected = false;
            this.sio.disconnect();
        }
        this.sio = null;
    }

    /**
     * 绑定事件
     * @param event 
     * @param fn 
     */
    on(event:string,callback?:Function){
        if(this.handlers[event]){
            console.log("event:" + event + "' handler has been registered.");
            return;
        }

        var handler = function(data){
            if(event != "disconnect" && typeof(data) == "string"){
                data = JSON.parse(data);
            }
            callback&&callback(data);
        };
        
        this.handlers[event] = handler; 
        if(this.sio){
            console.log("register:function " + event);
            this.sio.on(event,handler);
        }
    }

    /**
     * 击发服务器事件
     * @param event 
     * @param data 
     */
    emit(event:string,data?:object){
        if(this.sio && this.connected){
            if(data){
                let msg = JSON.stringify(data);
                this.sio.emit(event,msg);
                return;
            }
            this.sio.emit(event);
        }
    }
        
}

